﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Collections;

namespace ChatQQServer
{
    public partial class ChatServer : Form
    {
        public bool flag = false;
        Thread st;
        Thread ct;
        TcpListener tlst;
        Encoding ed;
        Socket socket;
        bool start = true;
        ArrayList clients = new ArrayList();
        public ChatServer()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
            tirlbl.Start();
        }

        private void tirlbl_Tick(object sender, EventArgs e)
        {
            tslbltime.Text = DateTime.Now.ToString();
            tslblzx.Text = clients.Count.ToString();
        }

        private void ChatServer_Load(object sender, EventArgs e)
        {
            System.Windows.Forms.Timer retrm = new System.Windows.Forms.Timer();
            retrm.Tick += new EventHandler(retrm_Tick);
            retrm.Interval = 5000;
            retrm.Start();
            ed = Encoding.Default;
        }

        void retrm_Tick(object sender, EventArgs e)
        {
            ArrayList ulst = new ArrayList();
            for (int i = 0; i < clients.Count; i++)
            {
                ClientBean cb = (ClientBean)clients[i];
                ulst.Add(cb.Uid);
            }
            DBcon con = new DBcon();
            con.notonline(ulst);
        }

        private void tlbar_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
        {
            if (e.Button==tlbar.Buttons[0])
            {
                
                tlbar.Buttons[0].Enabled = false;
                tlbar.Buttons[1].Enabled = true;
                mnustart_Click(sender, e);
                
                //MessageBox.Show("服务器开启");
            }
            if (e.Button == tlbar.Buttons[1])
            {
                
                tlbar.Buttons[0].Enabled = true;
                tlbar.Buttons[1].Enabled = false;
                close();
                
                //MessageBox.Show("服务器关闭");
            }
            if (e.Button == tlbar.Buttons[2])
            {
                txtsta.Clear();
                //MessageBox.Show("记录日志");
            }
            if (e.Button == tlbar.Buttons[3])
            {
                this.Close();
            }

        }

        private void mnustart_Click(object sender, EventArgs e)//启动服务器
        {
            start = true;
            txtsta.AppendText( "服务器正在启动…………" + "\r\n");
            try
            {
                IPAddress ip = IPAddress.Parse("192.168.1.2");
                tlst = new TcpListener(ip, 8098);
                tlst.Start();

            }
            catch (Exception ex)
            {
                txtsta.Text += "0" + ex.Message + "\r\n";
            }
            
            st = new Thread(new ThreadStart(ServerStart));
            st.Start();
            txtsta.AppendText( "服务器正在监听8098端口…………" + "\r\n");
            txtsta.AppendText( "服务器正常运行…………" + "\r\n");
        }
        private void ServerStart()
        {
            while (start)
            {
                try
                {
                    socket = tlst.AcceptSocket();
                    ct = new Thread(new ThreadStart(clientListener));
                    ct.Start();
                }
                catch (Exception) 
                {
                    //txtsta.Text +="1"+ ex.Message+"\r\n";
                    break; 
                }
                
            }
            
        }
        private void clientListener()
        {
            Socket s = socket;
            
            bool kill = true;
            while (kill)
            {
                try
                {
                    byte[] buffer = new byte[2048];
                    s.Receive(buffer);
                    string str = ed.GetString(buffer);
                    string[] strs = str.Split(new char[] { '|' }, 4);
                    if (strs[0] == "off")
                    {
                        txtsta.AppendText( "\r\n" + strs[1] + "正常下线……" + "\r\n");
                        for (int i = 0; i < clients.Count; i++)
                        {
                            ClientBean cb = (ClientBean)clients[i];
                            if (cb.Uid==strs[1])
                            {
                                DBcon con = new DBcon();
                                con.online(strs[1], 3);
                                lstshow.Items.RemoveAt(i);
                                clients.RemoveAt(i);
                                s.Close(); 
                                
                                cb._Thread.Abort();
                                cb._Sockets.Close();
                            }
                        }
                        kill = false;
                        break;
                    }
                    else if (strs[0] == "hide")
                    {
                        DBcon con = new DBcon();
                        con.online(strs[1], 2);
                    }
                    else if (strs[0] == "in")
                    {
                        for (int i = 0; i < clients.Count; i++)
                        {
                            ClientBean cb = (ClientBean)clients[i];
                            if (cb.Uid == strs[1])
                            {
                                loginmessage("have", strs[1],s);
                                ct.Abort();
                                return;
                            }
                        }
                        DBcon con = new DBcon();
                        bool yes = con.login(strs[1].Trim(), strs[2].Trim());
                        String my = con.myself(strs[1]);
                        if (yes)
                        {
                            loginmessage("ok", strs[1],s);
                            string messages = strs[1] + ":" + s.RemoteEndPoint + "上线";
                            lstshow.Items.Add(messages);
                            ClientBean cb = new ClientBean(strs[1], ct, s);
                            clients.Add(cb);
                            string fm = con.ferencemessage(strs[1]);
                            my = my + fm;
                            loginmessage("my", my, s);
                            con.online(strs[1],1);
                        }
                        else
                        {
                            loginmessage("no", strs[1],s);
                            ct.Abort();
                            break;
                        }
                        
                    }
                    else if (strs[0] == "on")
                    {
                        messageSend(strs[1].Trim(), strs[2].Trim(), strs[3]);
                        //txtsta.AppendText("\r\n" + strs[1] + "说:" + strs[3] + "\r\n");
                        txtsta.ScrollToCaret();
                    }

                    else if (strs[0] == "ref")
                    {
                        DBcon con = new DBcon();
                        string mess = con.ferenceonline(strs[1]);
                        loginmessage("refa", mess, s);
                    }
                    else if (strs[0] == "del")
                    {
                        DBcon con = new DBcon();
                        con.delference(strs[1],strs[2]);
                    }
                    
                }
                catch (Exception ex)
                {
                    kill = false;
                    //socket.Close();
                    try
                    {
                        for (int i = 0; i < clients.Count; i++)
                        {
                            ClientBean cb = (ClientBean)clients[i];
                            if (cb._Sockets == s)
                            {
                                lstshow.Items.RemoveAt(i);
                                txtsta.AppendText(cb.Uid + "丢失连接！"+ "\r\n");
                                DBcon con = new DBcon();
                                con.online(cb.Uid, 3);
                                clients.RemoveAt(i);
                                if (ct != null)
                                {
                                    //ct.Abort();
                                }
                                if (s != null)
                                {
                                    s.Close();
                                }
                            }
                        }
                        
                        break;
                    }
                    catch (Exception et)
                    {
                        txtsta.AppendText("丢失主机！"+et.Message+"\r\n");
                    }
                    
                    
                    txtsta.AppendText("2"+ ex.Message + "\r\n");

                }
                
            }
            //tlst.Stop();
            
        }

        private void mnuclose_Click(object sender, EventArgs e)//关闭服务器
        {
            close();
        }
        private void close()
        {
            txtsta.AppendText("服务器正在关闭…………" + "\r\n");
            start = false;
            foreach (ClientBean cb in clients)
            {
                cb._Thread.Abort();
                cb._Sockets.Close();
            }
            if (socket != null)
            {
                socket.Close();
            }
            
            if (tlst != null)
            {
                try
                {
                    tlst.Stop();
                }
                catch (Exception ex)
                {
                    txtsta.Text = ex.Message;
                }
                //tlst.Stop();
            }
            //while (tlst != null)
            //{
            //    tlst.Stop();
            //}
            if (st != null)
            {
                st.Abort();
            }



            txtsta.AppendText("服务器已经关闭…………" + "\r\n");
        }

        private void ChatServer_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult dr = MessageBox.Show("是否要退出服务器程序？", "确认退出", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (dr == DialogResult.Yes)
            {
                if (st != null)
                {
                    close();
                }
                flag = true;
            }
            else
            {
                flag = false; ;
            }
            
        }

        private void txtsta_TextChanged(object sender, EventArgs e)
        {
            txtsta.ScrollToCaret();
        }

        private void messageSend(string uid,string suid,string message)
        {
            foreach (ClientBean cb in clients)
            {
                if (suid==cb.Uid)
                {
                    String smeeage = "say|" + uid + "|" + message;
                    byte[] buffer = ed.GetBytes(smeeage.ToCharArray());
                    cb._Sockets.Send(buffer);
                }
            }
        }

        private void loginmessage(string cmd,string message,Socket s)
        {
            String smeeage = cmd + "|" + message;
            byte[] buffer = ed.GetBytes(smeeage.ToCharArray());
            s.Send(buffer);
                
        }
    }
}